home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
tex
/
dvi
/
dvipssrc.zoo
/
drawps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-26
|
19KB
|
688 lines
/*
* D R A W P S . C
*
* Changed to take magnification into account, 27 August 1990.
*
* (minor mods by don on 5 Jan 90 to accommodate highres PostScript)
*
* $Revision: 1.1 $
*
* $Log: drawPS.c,v $
* Revision 1.1 90/03/10 20:32:48 grunwald
* Initial revision
*
*
* 89/04/24: decouty@irisa.fr, priol@irisa.fr
* added three shading levels for fig,
* removed '\n' in cmdout() calls
*
* Revision 1.4 87/05/07 15:06:24 dorab
* relinked back hh to h and vv to v undoing a previous change.
* this was causing subtle quantization problems. the main change
* is in the definition of hconvPS and vconvPS.
*
* changed the handling of the UC seal. the PS file should now be
* sent via the -i option.
*
* Revision 1.3 86/04/29 23:20:55 dorab
* first general release
*
* Revision 1.3 86/04/29 22:59:21 dorab
* first general release
*
* Revision 1.2 86/04/29 13:23:40 dorab
* Added distinctive RCS header
*
*/
#ifndef lint
static char RCSid[] =
"@(#)$Header: /usr/local/src/TeX/Dvips-5.0.2/RCS/drawPS.c,v 1.1 90/03/10 20:32:48 grunwald Exp $ (UCLA)";
#endif
/*
the driver for handling the \special commands put out by
the tpic program as modified by Tim Morgan <morgan@uci.edu>
the co-ordinate system is with the origin at the top left
and the x-axis is to the right, and the y-axis is to the bottom.
when these routines are called, the origin is set at the last dvi position,
which has to be gotten from the dvi-driver (in this case, dvips) and will
have to be converted to device co-ordinates (in this case, by [hv]convPS).
all dimensions are given in milli-inches and must be converted to what
dvips has set up (i.e. there are convRESOLUTION units per inch).
it handles the following \special commands
pn n set pen size to n
pa x y add path segment to (x,y)
fp flush path
ip flush invisible path, i.e. do shading only
da l flush dashed - each dash is l (inches)
dt l flush dotted - one dot per l (inches)
sp [l] flush spline - optional l is dot/dash length
ar x y xr yr sa ea arc centered at (x,y) with x-radius xr
and y-radius yr, start angle sa (in rads),
end angle ea (in rads)
ia x y xr yr sa ea invisible arc with same parameters as above
sh [s] shade last path (box, circle, ellipse)
s = gray level (0 = white, 1 = black)
wh whiten last path (box, circle, ellipse)
bk blacken last path (box,circle, ellipse)
tx texture command - Added by T. Priol
(priol@irisa.fr), enhanced by M. Jourdan:
textures are translated into uniform gray levels
this code is in the public domain
written by dorab patel <dorab@cs.ucla.edu>
december 1985
released feb 1986
changes for dvips july 1987
*/
#ifdef TPIC /* rest of the file !! */
#include "structures.h"
#include <math.h> /* used in function "arc" */
#ifdef DEBUG
extern integer debug_flag;
#endif /* DEBUG */
/*
* external functions used here
*/
extern void cmdout();
extern void floatout();
extern void numout();
extern void error();
/*
* external variables used here
*/
extern integer hh,vv; /* the current x,y position in pixel units */
extern int actualdpi ;
extern int vactualdpi ;
extern integer mag ;
#define convRESOLUTION DPI
#define convVRESOLUTION VDPI
#define TRUE 1
#define FALSE 0
#define tpicRESOLUTION 1000 /* number of tpic units per inch */
/* convert from tpic units to PS units */
#define PixRound(a,b) zPixRound((integer)(a),(integer)(b))
#define convPS(x) PixRound((x),convRESOLUTION)
#define convVPS(x) PixRound((x),convVRESOLUTION)
/* convert from tpic locn to abs horiz PS locn */
#define hconvPS(x) (integer)(hh + convPS(x))
/* convert from tpic locn to abs vert PS locn */
#define vconvPS(x) (integer)(vv + convVPS(x))
/* convert to degrees */
#define convDeg(x) (360*(x)/(2*3.14159265358))
/* if PostScript had splines, i wouldnt need to store the path */
#define MAXPATHS 600 /* maximum number of path segments */
#define NONE 0 /* for shading */
#define BLACK 1 /* for shading */
#define GRAY 2 /* MJ; for shading */
#define WHITE 3 /* for shading */
/* the following defines are used to make the PostScript shorter;
the corresponding defines are in the PostScript prolog special.lpro */
#define MOVETO "a"
#define LINETO "li"
#define RCURVETO "rc"
#define RLINETO "rl"
#define STROKE "st"
#define FILL "fil"
#define NEWPATH "np"
#define CLOSEPATH "closepath"
/*
* STROKE and FILL must restore the current point to that
* saved by NEWPATH
*/
static integer xx[MAXPATHS], yy[MAXPATHS]; /* the current path in milli-inches */
static integer pathLen = 0; /* the current path length */
static integer shading = NONE; /* what to shade the last figure */
static integer penSize = 2; /* pen size in PS units */
/* forward declarations */
/* static void doShading(); */
static integer zPixRound(); /* (int)(x/y)PixRound((int)x,(int)y) */
static double shadetp = 0.5;
/* shading level, initialized as requested by tpic 2.0 -- MJ */
void
setPenSize(cp)
char *cp;
{
long ps;
if (sscanf(cp, " %ld ", &ps) != 1)
{
error("Illegal .ps command format");
return;
}
penSize = convPS(ps);
numout((integer)penSize);
cmdout("setlinewidth");
} /* end setPenSize */
void
addPath(cp)
char *cp;
{
long x,y;
if (++pathLen >= MAXPATHS) error("! Too many points");
if (sscanf(cp, " %ld %ld ", &x, &y) != 2)
error("! Malformed path expression");
xx[pathLen] = x;
yy[pathLen] = y;
} /* end of addPath */
void
arc(cp, invis)
char *cp;
int invis;
{
long xc, yc, xrad, yrad;
float startAngle, endAngle;
if (sscanf(cp, " %ld %ld %ld %ld %f %f ", &xc, &yc, &xrad, &yrad,
&startAngle, &endAngle) != 6)
{
error("Illegal arc specification");
return;
}
/* To have filled ellipses/circles also have borders, we duplicate the object
specification; first time we emit a FILL command, second time we emit a
STROKE command.
There certainly exists a better way to do that in PostScript, by
remembering the object specification (path) across the fill command.
However I (MJ) am completely unproficient at PostScript...
*/
/* we need the newpath since STROKE doesnt do a newpath */
if (shading) {
/* first time for shading */
cmdout(NEWPATH);
numout((integer)hconvPS(xc));
numout((integer)vconvPS(yc));
numout((integer)convPS(xrad));
if (xrad != yrad && VDPI == DPI)
numout((integer)convPS(yrad));
floatout(convDeg(startAngle));
floatout(convDeg(endAngle));
if (xrad == yrad && VDPI == DPI) /* for arcs and circles */
cmdout("arc");
else
cmdout("ellipse");
cmdout(FILL);
shading = NONE;
cmdout("0 setgray"); /* default of black */
}
if (!invis) {
/* There is a problem with tpic 2.0's handling of dotted ellipses.
In most (all?) cases, after conversion to degrees and rounding
to integers, startAngle and endAngle become the same, so nothing,
not even a dot (as requested), is printed in the output (at least
on my Apple LaserWriter).
So I (MJ) singled out this case.
*/
float degStAng = convDeg(startAngle),
degEnAng = convDeg(endAngle);
cmdout(NEWPATH); /* save current point */
if (degStAng != degEnAng) { /* normal case */
numout((integer)hconvPS(xc));
numout((integer)vconvPS(yc));
numout((integer)convPS(xrad));
if (xrad != yrad)
numout((integer)convPS(yrad));
floatout(degStAng);
floatout(degEnAng);
if (xrad == yrad) /* for arcs and circles */
cmdout("arc");
else
cmdout("el